package com.module.ble.widget

import android.annotation.SuppressLint
import android.content.Context
import android.graphics.Canvas
import android.graphics.DashPathEffect
import android.graphics.LinearGradient
import android.graphics.Paint
import android.graphics.Path
import android.graphics.Point
import android.graphics.Rect
import android.graphics.Shader
import android.graphics.Typeface
import android.util.AttributeSet
import android.util.Log
import android.view.MotionEvent
import android.view.View
import com.common.base.app.extras.dp2px
import com.common.base.utils.JsonUtils
import com.common.base.utils.ViewUtils.getColor
import com.module.ble.R
import com.module.ble.data.bean.CusChartData
import com.module.ble.utils.CommonCusHealthType
import kotlin.math.abs
import kotlin.math.roundToInt

/**
 *
 * 作者：sosou
 *
 * 版本：1.0
 *
 * 创建日期：2024/10/24
 *
 * 描述：折线日图表
 *
 * 修订历史：
 *
 */
class BrokenLineChart(context: Context, attrs: AttributeSet?=null) : View(context,attrs){

    private var businessType = CommonCusHealthType.HEARTRATE.value

    //屏幕宽高
    private var scrWidth = 0f
    private var scrHeight = 0f
    private var xData: Array<String> = arrayOf("00", "06", "12", "18", "24")
    private var yData: Array<Int> = arrayOf(200, 150, 100, 50, 0)
    private var heartData = mutableListOf<CusChartData>()
    private lateinit var paintLine: Paint //y轴线
    private lateinit var zeroPaintLine: Paint //y轴0线
    private lateinit var paintGradientLine: Paint //指示渐变竖线
    private lateinit var paintXText: Paint //x轴坐标
    private lateinit var paintYText: Paint //y轴坐标
    private lateinit var coordinatePoint: Paint //坐标点
    private lateinit var paintSolidLine: Paint// 实线的画笔
    private lateinit var paintPolyline: Paint //折线
    private lateinit var paintPolyShadow: Paint //折线阴影
    private lateinit var paintRound: Paint  //指示滑块圆
    private lateinit var paintBessel: Paint  //滑块底部

    private var xSlider = 0f //滑块的x轴位置

    private var mLinePath: Path  //折线路径

    private val curveCircleRadius = 12f
    private var mPath: Path  //滑块贝塞尔

    //第一条曲线的坐标
    private val mFirstCurveStartPoint = Point()
    private val mFirstCurveEndPoint = Point()
    private val mFirstCurveControlPoint1 = Point()
    private val mFirstCurveControlPoint2 = Point()

    //第二条曲线的坐标
    private var mSecondCurveStartPoint = Point()
    private val mSecondCurveEndPoint = Point()
    private val mSecondCurveControlPoint1 = Point()
    private val mSecondCurveControlPoint2 = Point()

    private val margin = 20f //左右两边距离
    private var xWithStart = 0f //x轴的起始点
    private var xWithEnd = 0f  //x轴结束点
    private var ySpacing = 0f //高度分割份数后间距
    private var xSpacing = 0f //x轴柱子分割份数后间距
    private var xTextSpacing = 0f //x轴文字分割份数后间距

    // 添加属性来缓存计算结果
    private var lastIndex = -1
    // 优化Path对象的重用
    private val tmpPath = Path()
    // 添加属性来缓存shader
    private var polyShadowShader: Shader? = null
    // 添加控制变量
    private var showZeroLine = true // 控制是否显示0刻度线
    private var zeroLineColor= getColor(R.color.c_f97975)    // 0刻度线线条颜色

    private var paintPolylineDefaultColor = getColor(R.color.c_f97975)
    private var maxGapForConnection = 20 // 间隔阈值默认值为5
    // 添加控制变量
    private var showSlider = false

    private var showYAxisLabels = true  // 控制是否显示Y轴文字
    private val yAxisTextPadding = dp2px(8f)  // 文字左边的间距// 添加一个属性来存储最大文字宽度
    private var maxYAxisTextWidth = 0f

    private var onDayMoveListener: ((isPre: Boolean) -> Unit)? = null
    private var onDaySelectListener: ((time: Long, heart: Float) -> Unit)? = null

    init {
        setLayerType(LAYER_TYPE_SOFTWARE, null)
        // 设置绘制缓存
        isDrawingCacheEnabled = true

        // 避免不必要的父布局请求
        setWillNotDraw(false)
        mLinePath = Path()
        mPath = Path()
        initPaint()
    }

    /**
     * 初始化画笔
     */
    private fun initPaint() {

        paintLine = Paint().apply {
            style = Paint.Style.STROKE
            strokeWidth = 1f
            color = getColor(R.color.c_2e2e2e)
            // 设置虚线效果
            // 第一个参数数组表示虚线的格式：[实线长度, 空白长度]
            pathEffect = DashPathEffect(floatArrayOf(12f, 6f), 0f)
        }
        zeroPaintLine= Paint().apply {
            style = Paint.Style.STROKE
            strokeWidth = 1f
            color = zeroLineColor
            // 设置虚线效果
            // 第一个参数数组表示虚线的格式：[实线长度, 空白长度]
            pathEffect = DashPathEffect(floatArrayOf(12f, 6f), 0f)
        }

        paintGradientLine = Paint()
        paintGradientLine.style = Paint.Style.STROKE
        paintGradientLine.strokeWidth = 2f

        paintPolyShadow = Paint()
        paintPolyShadow.style = Paint.Style.FILL

        paintXText = Paint()
        paintXText.isAntiAlias = true
        paintXText.strokeWidth = 1f
        paintXText.textSize = dp2px(12f)
        paintXText.textAlign = Paint.Align.CENTER
        paintXText.color = getColor(R.color.black)

        paintYText = Paint()
        paintYText.isAntiAlias = true
        paintYText.textSize = dp2px(11f)
        paintYText.strokeWidth = 1f
        paintYText.textAlign = Paint.Align.RIGHT
        paintYText.color = getColor(R.color.color_808080)

        // 虚线画笔(原来的paintPolyline)
        paintPolyline = Paint().apply {
            style = Paint.Style.FILL
            strokeWidth = 3f
            isAntiAlias = true
            pathEffect = DashPathEffect(floatArrayOf(3f, 3f), 0f)
            color = paintPolylineDefaultColor
        }

        // 新增实线画笔
        paintSolidLine = Paint().apply {
            style = Paint.Style.FILL
            strokeWidth = 3f
            isAntiAlias = true
            color = paintPolylineDefaultColor
        }

        paintRound = Paint()
        paintRound.style = Paint.Style.FILL
        paintRound.isAntiAlias = true
        paintRound.color = zeroLineColor

        paintBessel = Paint()
        paintBessel.style = Paint.Style.FILL
        paintBessel.isAntiAlias = true
        paintBessel.color = getColor(R.color.color_eeeded)

        coordinatePoint = Paint()
        coordinatePoint.style = Paint.Style.FILL
        coordinatePoint.strokeWidth = 3f
        coordinatePoint.isAntiAlias = true
        coordinatePoint.color = paintPolylineDefaultColor
    }

    // 添加一个方法来计算最大文字宽度
    private fun calculateMaxYAxisTextWidth() {
        maxYAxisTextWidth = yData.map { value ->
            paintYText.measureText(value.toString())
        }.maxOrNull() ?: 0f
    }

    override fun onSizeChanged(w: Int, h: Int, oldw: Int, oldh: Int) {
        super.onSizeChanged(w, h, oldw, oldh)
        scrWidth = width.toFloat()
        scrHeight = height.toFloat()

        updateChartDimensions()
    }

    private var mDownX = 0f
    private var mDownY = 0f

    private var isSlider = false//是否开启触摸模式

    @SuppressLint("ClickableViewAccessibility")
    override fun onTouchEvent(event: MotionEvent): Boolean {
        if (!showSlider) return false

        if (heartData.isNullOrEmpty()) return true//无数据是直接透传触摸

        when (event.action) {
            MotionEvent.ACTION_DOWN -> {
                mDownX = event.x
                mDownY = event.y
                return true
            }

            MotionEvent.ACTION_MOVE -> {
                // 限制滑动范围
                xSlider = event.x.coerceIn(xWithStart, xWithEnd)

                // 计算当前位置对应的精确索引
                val exactIndex = ((xSlider - xWithStart) / xSpacing)
                val lowerIndex = exactIndex.toInt()
                val upperIndex = (lowerIndex + 1).coerceAtMost(heartData.size - 1)

                // 计算与两个相邻索引的距离
                val lowerDistance = abs(xSlider - (xWithStart + lowerIndex * xSpacing))
                val upperDistance = abs(xSlider - (xWithStart + upperIndex * xSpacing))

                // 选择最近的有效索引
                val nearestIndex = if (lowerDistance <= upperDistance) {
                    findNearestValidIndex(lowerIndex)
                } else {
                    findNearestValidIndex(upperIndex)
                }

                if (nearestIndex in heartData.indices) {
                    xSlider = xWithStart + nearestIndex * xSpacing
                    onDaySelectListener?.invoke(
                        heartData[nearestIndex].createdTime,
                        heartData[nearestIndex].mValue
                    )
                }

                invalidate()
                return true
            }

            MotionEvent.ACTION_UP, MotionEvent.ACTION_CANCEL -> {
                // 计算精确索引
                val exactIndex = ((xSlider - xWithStart) / xSpacing)
                val nearestIndex = findNearestValidIndex(exactIndex.roundToInt())

                if (nearestIndex != -1) {
                    xSlider = xWithStart + nearestIndex * xSpacing
                    if (nearestIndex in heartData.indices) {
                        onDaySelectListener?.invoke(
                            heartData[nearestIndex].createdTime,
                            heartData[nearestIndex].mValue
                        )
                    }
                    invalidate()
                }
                return true
            }
        }
        return super.onTouchEvent(event)
    }

    private fun findNearestValidIndex(currentIndex: Int): Int {
        if (currentIndex >= heartData.size) return -1

        // 如果当前位置就是有效点，直接返回
        if (heartData[currentIndex].mValue > 0) {
            return currentIndex
        }

        var leftIndex = currentIndex
        var rightIndex = currentIndex
        var minDistance = Float.MAX_VALUE
        var nearestIndex = currentIndex

        // 设置一个合理的搜索范围
        val searchRange = 5

        // 向左右同时搜索最近的有效点
        for (i in 0..searchRange) {
            // 检查左侧点
            if (leftIndex >= 0) {
                if (heartData[leftIndex].mValue > 0) {
                    val distance = abs(xWithStart + currentIndex * xSpacing - (xWithStart + leftIndex * xSpacing))
                    if (distance < minDistance) {
                        minDistance = distance
                        nearestIndex = leftIndex
                    }
                }
                leftIndex--
            }

            // 检查右侧点
            if (rightIndex < heartData.size) {
                if (heartData[rightIndex].mValue > 0) {
                    val distance = abs(xWithStart + currentIndex * xSpacing - (xWithStart + rightIndex * xSpacing))
                    if (distance < minDistance) {
                        minDistance = distance
                        nearestIndex = rightIndex
                    }
                }
                rightIndex++
            }

            // 如果已经超出数据范围，且找到了有效点，则返回
            if (leftIndex < 0 && rightIndex >= heartData.size && nearestIndex != currentIndex) {
                break
            }
        }

        return nearestIndex
    }

    @SuppressLint("DrawAllocation")
    override fun onDraw(canvas: Canvas) {
        super.onDraw(canvas)

        // 使用clipRect减少不必要的绘制区域
        canvas.save()
        canvas.clipRect(0f, 0f, scrWidth, scrHeight)

        //画y轴方向横线与文字
        drawY(canvas)
        //垂直渐变线
        drawGradientLine(canvas)
        //折线
        drawPolyline(canvas)
        //底部
        drawBessel(canvas)
        //画x轴方向文字
        drawX(canvas)

        canvas.restore()
    }

    private fun drawX(canvas: Canvas) {
        xData.forEachIndexed { index, s ->
            val x = xWithStart + xTextSpacing * index

            if (showSlider) {
                // 原有的滑块模式下的文字绘制逻辑
                val dis = abs(x - xSlider)
                val besselTopY = ySpacing * 5.3f - curveCircleRadius * 1.7f
                var y = besselTopY + paintXText.textSize / 2

                if (dis < xTextSpacing / 2) {
                    paintXText.typeface = Typeface.DEFAULT_BOLD
                    val liftRatio = (1 - dis / (xTextSpacing / 2)).coerceIn(0f, 1f)
                    val liftDistance = 32f
                    y -= liftDistance * liftRatio
                } else {
                    paintXText.typeface = Typeface.DEFAULT
                }

                canvas.drawText(s, x, y, paintXText)
            } else {
                // 无滑块模式下的文字绘制逻辑
                paintXText.typeface = Typeface.DEFAULT
                // 直接在底部绘制文字，设置一个固定的底部边距
                val y = height - dp2px(10f)
                canvas.drawText(s, x, y, paintXText)
            }
        }
    }

    private fun drawPolyline(canvas: Canvas) {
        val validPoints = heartData.mapIndexedNotNull { index, data ->
            if (data.mValue > 0) index to data.mValue else null
        }

        if (validPoints.isEmpty()) {
            Log.d("HeartRateChart", "No valid points to draw")
            return
        }

        // 根据业务类型计算值的映射范围
        val (maxValue, minValue) = if (businessType == CommonCusHealthType.BODYTEMP.value) {
            42 to 26  // 体温范围
        } else {
            200 to 0  // 心率范围
        }
        val valueRange = maxValue - minValue
        val pixelPerUnit = (ySpacing * 4) / valueRange

        // 如果有多个点，绘制连线和阴影
        if (validPoints.size > 1) {
            validPoints.zipWithNext().forEach { (current, next) ->
                val (currentIndex, currentValue) = current
                val (nextIndex, nextValue) = next

                val x0 = xWithStart + (currentIndex * xSpacing)
                // 根据业务类型映射Y轴坐标
                val y0 = ySpacing + (maxValue - currentValue) * pixelPerUnit
                val x1 = xWithStart + (nextIndex * xSpacing)
                val y1 = ySpacing + (maxValue - nextValue) * pixelPerUnit

                // 计算两点之间的间隔
                val gap = nextIndex - currentIndex
                val isConnected = gap <= maxGapForConnection

                // 选择使用的画笔
                val linePaint = if (isConnected) {
                    paintSolidLine.apply {
                        color = paintPolylineDefaultColor
                    }
                } else {
                    paintPolyline.apply {
                        color = paintPolylineDefaultColor
                    }
                }

                // 只在连续数据时绘制阴影
                if (isConnected) {
                    drawPolyShadow(x0, y0, x1, y1, canvas)
                }

                // 绘制折线
                canvas.drawLine(x0, y0, x1, y1, linePaint)
            }

            // 为最后一个点添加延伸阴影
            val (lastIndex, lastValue) = validPoints.last()
            val x = xWithStart + (lastIndex * xSpacing)
            val y = ySpacing + (maxValue - lastValue) * pixelPerUnit
            val extendedX = x + xSpacing * 2
            drawPolyShadow(x, y, extendedX, y, canvas)

        } else {
            // 如果只有一个点的处理
            val (index, value) = validPoints.first()
            val x = xWithStart + (index * xSpacing)
            val y = ySpacing + (maxValue - value) * pixelPerUnit
            canvas.drawCircle(x, y, 4f, paintSolidLine)
            val extendedX = x + xSpacing * 2
            drawPolyShadow(x, y, extendedX, y, canvas)
        }

        // 绘制选中点的指示器
        if (showSlider) {
            validPoints.forEach { (index, value) ->
                val x = xWithStart + (index * xSpacing)
                val y = ySpacing + (maxValue - value) * pixelPerUnit

                if (abs(x - xSlider) < xSpacing / 2) {
                    coordinatePoint.color = getColor(R.color.white)
                    canvas.drawCircle(x, y, 10f, coordinatePoint)
                    coordinatePoint.color = getColor(R.color.c_5bfdb9)
                    canvas.drawCircle(x, y, 7f, coordinatePoint)
                    onDaySelectListener?.invoke(heartData[index].createdTime, value)
                }
            }
        }
    }

    private fun drawY(canvas: Canvas) {
        for (i in 0..4) {
            val lineY = ySpacing * (i + 1)
            val text = yData[i].toString()

            // 计算文字尺寸
            val textBounds = Rect()
            paintYText.getTextBounds(text, 0, text.length, textBounds)
            val textHeight = textBounds.height()
            val currentTextWidth = paintYText.measureText(text)

            // 计算文字在统一宽度内的居中位置
            val textAreaStartX = scrWidth - margin - maxYAxisTextWidth
            val textX = textAreaStartX + (maxYAxisTextWidth - currentTextWidth) / 2

            // 计算线条的结束位置
            val lineEndX = if (showYAxisLabels) {
                textAreaStartX - yAxisTextPadding
            } else {
                scrWidth - margin
            }

            // 判断是否是0刻度线
            if (i == 4) {
                if (showZeroLine) {
                    canvas.drawLine(margin, lineY, lineEndX, lineY, zeroPaintLine)
                    if (showYAxisLabels) {
                        paintYText.color = getColor(R.color.color_808080)
                        val textY = lineY + textHeight / 2
                        paintYText.textAlign = Paint.Align.LEFT
                        canvas.drawText(text, textX, textY, paintYText)
                    }
                }
            } else {
                canvas.drawLine(margin, lineY, lineEndX, lineY, paintLine)
                if (showYAxisLabels) {
                    paintYText.color = getColor(R.color.color_808080)
                    val textY = lineY + textHeight / 2
                    paintYText.textAlign = Paint.Align.LEFT
                    canvas.drawText(text, textX, textY, paintYText)
                }
            }
        }
    }

    private fun drawBessel(canvas: Canvas) {
        // 如果不显示滑块，直接返回
        if (!showSlider) return

        //系数值增大滑块位置下移,减小则会使滑块位置上移
        val bottomY = ySpacing * 5.4f

        // 微调贝塞尔曲线参数
        val blueCircleRadius = curveCircleRadius * 1.8f
        // 减小曲线凸起高度，使文字更贴近
        val curveHeight = blueCircleRadius * 0.6f
        val curveWidth = blueCircleRadius * 3.8f

        // 调整圆点位置，减小乘数使圆点位置略微上移(直接减小circleY的值来使圆点上移10px)
        val circleY = bottomY + blueCircleRadius * 0.4f-10f

        // 第一条曲线的起始点和控制点设置
        mFirstCurveStartPoint[(xSlider - curveWidth).toInt()] = bottomY.toInt()
        mFirstCurveEndPoint[xSlider.toInt()] = (circleY - blueCircleRadius - curveHeight).toInt()
        mSecondCurveStartPoint = mFirstCurveEndPoint
        mSecondCurveEndPoint[(xSlider + curveWidth).toInt()] = bottomY.toInt()

        // 控制点调整，使曲线更平滑
        mFirstCurveControlPoint1[(mFirstCurveStartPoint.x + curveWidth * 0.4f).toInt()] =
            mFirstCurveStartPoint.y
        mFirstCurveControlPoint2[(mFirstCurveEndPoint.x - curveWidth * 0.4f).toInt()] =
            mFirstCurveEndPoint.y

        mSecondCurveControlPoint1[(mSecondCurveStartPoint.x + curveWidth * 0.4f).toInt()] =
            mSecondCurveStartPoint.y
        mSecondCurveControlPoint2[(mSecondCurveEndPoint.x - curveWidth * 0.4f).toInt()] =
            mSecondCurveEndPoint.y

        // 绘制贝塞尔曲线路径
        mPath.reset()
        mPath.moveTo(0f, bottomY)
        mPath.lineTo(mFirstCurveStartPoint.x.toFloat(), mFirstCurveStartPoint.y.toFloat())
        mPath.cubicTo(
            mFirstCurveControlPoint1.x.toFloat(), mFirstCurveControlPoint1.y.toFloat(),
            mFirstCurveControlPoint2.x.toFloat(), mFirstCurveControlPoint2.y.toFloat(),
            mFirstCurveEndPoint.x.toFloat(), mFirstCurveEndPoint.y.toFloat()
        )
        mPath.cubicTo(
            mSecondCurveControlPoint1.x.toFloat(), mSecondCurveControlPoint1.y.toFloat(),
            mSecondCurveControlPoint2.x.toFloat(), mSecondCurveControlPoint2.y.toFloat(),
            mSecondCurveEndPoint.x.toFloat(), mSecondCurveEndPoint.y.toFloat()
        )
        mPath.lineTo(scrWidth, bottomY)
        mPath.lineTo(scrWidth, scrHeight)
        mPath.lineTo(0f, scrHeight)
        mPath.close()

        // 绘制路径和圆点
        canvas.drawPath(mPath, paintBessel)
        canvas.drawCircle(xSlider, circleY, blueCircleRadius, paintRound)
    }

    private fun drawPolyShadow(x0: Float, y0: Float, x1: Float, y1: Float, canvas: Canvas) {
        tmpPath.reset()
        tmpPath.moveTo(x0, ySpacing * 5f)
        tmpPath.lineTo(x0, y0)
        tmpPath.lineTo(x1, y1)
        tmpPath.lineTo(x1, ySpacing * 5f)
        tmpPath.close()

        // 根据业务类型设置渐变
        polyShadowShader = when (businessType) {
            CommonCusHealthType.BODYTEMP.value -> { // 体温模式
                val tempRange = 42 - 26  // 温度范围(42-26=16度)
                val pixelPerDegree = (ySpacing * 4) / tempRange  // 每度对应的像素高度
                val maxTemp = heartData.maxOfOrNull { it.mValue } ?: 26f
                LinearGradient(
                    0f,
                    ySpacing + (42 - maxTemp) * pixelPerDegree,
                    0f,
                    ySpacing * 5f,
                    intArrayOf(
                        getColor(R.color.c_61d1ba),
                        getColor(R.color.transparent)
                    ),
                    null,
                    Shader.TileMode.MIRROR
                )
            }
            else -> { // 心率模式
                val heartRange = 200 // 心率范围(0-200)
                val pixelPerUnit = (ySpacing * 4) / heartRange  // 每单位对应的像素高度
                val maxHeart = heartData.maxOfOrNull { it.mValue } ?: 0f
                LinearGradient(
                    0f,
                    ySpacing + (200 - maxHeart) * pixelPerUnit,
                    0f,
                    ySpacing * 5f,
                    intArrayOf(
                        getColor(R.color.c_f97975),
                        getColor(R.color.transparent)
                    ),
                    null,
                    Shader.TileMode.MIRROR
                )
            }
        }

        paintPolyShadow.shader = polyShadowShader
        canvas.drawPath(tmpPath, paintPolyShadow)
    }

    fun setValue(value: List<CusChartData>, resetPosition: Boolean = true): BrokenLineChart {
        heartData.clear()
        heartData = value.take(1440).toMutableList()

        val temp = JsonUtils.toJson(heartData)

        val firstValidIndex = heartData.indexOfFirst { it.mValue > 0 }

        if (resetPosition && firstValidIndex != -1) {
            xSlider = xWithStart + (firstValidIndex * xSpacing)
            Log.d("HeartRateChart", "New xSlider position: $xSlider")
        }

        polyShadowShader = null
        lastIndex = -1

        if (width > 0 && height > 0) {
            updateChartDimensions()
            invalidate()
        }
        return this
    }

    private fun drawGradientLine(canvas: Canvas) {//渐变竖线
        if (!showSlider) return  // 如果不显示滑块，直接返回

        // 可以通过调整这些系数来微调长度和位置
        val startRatio = 1f  // 增大这个值会让线条起点更低
        val endRatio = 4.8f    // 减小这个值会让线条终点更高

        val startY = ySpacing * startRatio
        val endY = ySpacing * endRatio

        val mLinearGradient = LinearGradient(
            xSlider, startY, xSlider, endY,
            intArrayOf(
                getColor(R.color.transparent),
                zeroLineColor,
                getColor(R.color.transparent)
            ), null, Shader.TileMode.MIRROR
        )
        paintGradientLine.shader = mLinearGradient

        if (ySpacing > 0) {
            canvas.drawLine(xSlider, startY, xSlider, endY, paintGradientLine)
        }
    }

    // 更新图表尺寸的方法
    private fun updateChartDimensions() {
        val chartHeight = height * 1.05f
        ySpacing = chartHeight / 6f

        if (width == 0) return

        // 确保已经计算了最大文字宽度
        calculateMaxYAxisTextWidth()

        xWithStart = margin + paintXText.measureText(xData[0]) / 2
        // 根据是否显示Y轴文字调整结束位置
        xWithEnd = if (showYAxisLabels) {
            scrWidth - margin - maxYAxisTextWidth - yAxisTextPadding
        } else {
            scrWidth - margin
        }

        val totalWidth = xWithEnd - xWithStart
        xTextSpacing = totalWidth / (xData.size - 1)
        xSpacing = totalWidth / 1439f

        xSlider = xWithStart
    }

    fun setOnDaySelectListener(l: ((time: Long, heart: Float) -> Unit)): BrokenLineChart {
        this.onDaySelectListener = l
        return this
    }

    fun setOnDayMoveListener(l: ((index: Boolean) -> Unit)): BrokenLineChart {
        this.onDayMoveListener = l
        return this
    }

    fun setPaintDefaultColor(color: Int): BrokenLineChart {
        paintPolylineDefaultColor = color
        invalidate()
        return this
    }

    fun setShowZeroLineColor(mColor: Int): BrokenLineChart {
        this.zeroLineColor = mColor
        this.zeroPaintLine.color = zeroLineColor
        this.paintRound.color = zeroLineColor

        invalidate()
        return this
    }

    /**
     * 设置是否显示0刻度线
     * @param show Boolean
     */
    fun setShowZeroLine(show: Boolean): BrokenLineChart {
        this.showZeroLine = show
        invalidate()
        return this
    }

    /**
     * 设置是否显示底部滑块
     * @param show Boolean true显示滑块和指示器，false只显示时间文字
     */
    fun setShowSlider(show: Boolean): BrokenLineChart {
        this.showSlider = show
        invalidate()
        return this
    }


    fun setShowYAxisLabel(show: Boolean): BrokenLineChart {
        this.showYAxisLabels = show
        invalidate()  // 需要重新布局因为会影响图表宽度
        return this
    }

    fun setBusinessType(type: Int): BrokenLineChart {
        businessType = type
        // 根据业务类型设置对应的刻度值
        yData = when (type) {
            CommonCusHealthType.HEARTRATE.value -> {
                arrayOf(200, 150, 100, 50, 0)
            }
            else -> {
                arrayOf(42, 38, 34, 30, 26)
            }
        }
        invalidate()
        return this
    }
}